﻿using DifyToOpenAI.Common;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;

namespace DifyToOpenAI.Models
{

    /// <summary>
    /// 表示一个完整的聊天补全响应。
    /// Represents a complete chat completion response.
    /// </summary>
    public class ChatCompletion
    {
        public ChatCompletion() { }
        public ChatCompletion(string content, string id = "", string role = "assistant")
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                // this.id = Guid.NewGuid().ToString();
            }
            else { this.id = id; }

            this.choices = new List<Choice>();
            Choice choice = new Choice();
            choice.message = new ResponseMessage();
            choice.message.content = content;
            choice.message.role = role;
            this.choices.Add(choice);
        }
        /// <summary>
        /// 响应的唯一标识符。
        /// A unique identifier for the chat completion.
        /// </summary>
        public string? id { get; set; } = Guid.NewGuid().ToString();

        /// <summary>
        /// 对象类型，通常是 "chat.completion"。
        /// The object type, which is typically "chat.completion".
        /// </summary>
        [JsonPropertyName("object")]
        public string? @object { get; set; }

        /// <summary>
        /// 响应创建时的 Unix 时间戳。
        /// The Unix timestamp (in seconds) of when the completion was created.
        /// </summary>
        public long? created { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

        /// <summary>
        /// 所使用的模型。
        /// The model used for the chat completion.
        /// </summary>
        public string? model { get; set; }

        /// <summary>
        /// 补全选择的列表。
        /// A list of chat completion choices.
        /// </summary>
        public List<Choice>? choices { get; set; } = new List<Choice>();

        /// <summary>
        /// 本次请求的 token 使用情况统计。
        /// Usage statistics for the completion request.
        /// </summary>
        public Usage? usage { get; set; }

        /// <summary>
        /// 使用的服务层级。
        /// The service tier used for the request.
        /// </summary>
        public string? service_tier { get; set; }

        [JsonIgnore]
        private string realJsonstring = string.Empty;

        /// <summary>
        /// 获取或设置请求的真实 JSON 字符串表示。设置此属性将触发反序列化。
        /// Gets or sets the real JSON string representation of the request. Setting this property will trigger deserialization.
        /// </summary>
        [JsonIgnore]
        public string? RealJsonstring
        {
            get { return realJsonstring; }
            set
            {
                realJsonstring = value!;
                try
                {
                    DeserializeChatCompletion(value!);
                }
                catch (Exception)
                {
                    // 可以选择记录异常或按需处理
                    // Optionally log the exception or handle it as needed
                }
            }
        }

        /// <summary>
        /// 将 JSON 字符串反序列化到当前的 ChatCompletion 实例中。
        /// 此方法逐个解析 JSON 属性，即使某些属性解析失败，也会继续尝试解析其他属性。
        /// Deserializes a JSON string into the current ChatCompletion instance.
        /// This method parses JSON properties one by one, continuing even if some fail.
        /// </summary>
        /// <param name="json">需要解析的 JSON 字符串。The JSON string to be parsed.</param>
        public virtual void DeserializeChatCompletion(string json)
        {
            if (string.IsNullOrEmpty(json)) return;

            var jsonNode = JsonNode.Parse(json);
            if (jsonNode == null) return;

            // --- 解析顶层属性 ---
            try { if (jsonNode["id"] != null) this.id = jsonNode["id"]!.GetValue<string>(); } catch { }
            try { if (jsonNode["object"] != null) this.@object = jsonNode["object"]!.GetValue<string>(); } catch { }
            try { if (jsonNode["created"] != null) this.created = jsonNode["created"]!.GetValue<long>(); } catch { }
            try { if (jsonNode["model"] != null) this.model = jsonNode["model"]!.GetValue<string>(); } catch { }
            try { if (jsonNode["service_tier"] != null) this.service_tier = jsonNode["service_tier"]!.GetValue<string>(); } catch { }

            // --- 解析 choices 数组 ---
            try
            {
                var choicesNode = jsonNode["choices"]?.AsArray();
                if (choicesNode != null)
                {
                    this.choices = new List<Choice>();
                    foreach (var choiceNode in choicesNode)
                    {
                        if (choiceNode == null) continue;
                        var choice = new Choice();
                        try { if (choiceNode["index"] != null) choice.index = choiceNode["index"]!.GetValue<int>(); } catch { }
                        try { if (choiceNode["finish_reason"] != null) choice.finish_reason = choiceNode["finish_reason"]!.GetValue<string>(); } catch { }
                        try { if (choiceNode["logprobs"] != null) choice.logprobs = choiceNode["logprobs"]!.ToJsonString(); } catch { }

                        // 解析 message 对象
                        try
                        {
                            var messageNode = choiceNode["message"];
                            if (messageNode != null)
                            {
                                choice.message = new ResponseMessage();
                                try { if (messageNode["role"] != null) choice.message.role = messageNode["role"]!.GetValue<string>(); } catch { }
                                try { if (messageNode["content"] != null) choice.message.content = messageNode["content"]!.GetValue<string>(); } catch { }
                                try { if (messageNode["refusal"] != null) choice.message.refusal = messageNode["refusal"]!.GetValue<string>(); } catch { }
                                try
                                {
                                    if (messageNode["annotations"] != null)
                                    {
                                        choice.message.annotations = messageNode["annotations"]!.AsArray().Select(n => n as object).ToList()!;
                                    }
                                }
                                catch { }
                            }
                        }
                        catch { }
                        this.choices.Add(choice);
                    }
                }
            }
            catch { }

            // --- 解析 usage 对象 ---
            try
            {
                var usageNode = jsonNode["usage"];
                if (usageNode != null)
                {
                    this.usage = new Usage();
                    try { if (usageNode["prompt_tokens"] != null) this.usage.prompt_tokens = usageNode["prompt_tokens"]!.GetValue<int>(); } catch { }
                    try { if (usageNode["completion_tokens"] != null) this.usage.completion_tokens = usageNode["completion_tokens"]!.GetValue<int>(); } catch { }
                    try { if (usageNode["total_tokens"] != null) this.usage.total_tokens = usageNode["total_tokens"]!.GetValue<int>(); } catch { }

                    // 解析 prompt_tokens_details
                    try
                    {
                        var promptDetailsNode = usageNode["prompt_tokens_details"];
                        if (promptDetailsNode != null)
                        {
                            this.usage.prompt_tokens_details = new PromptTokensDetails();
                            try { this.usage.prompt_tokens_details.cached_tokens = promptDetailsNode["cached_tokens"]?.GetValue<int>(); } catch { }
                            try { this.usage.prompt_tokens_details.audio_tokens = promptDetailsNode["audio_tokens"]?.GetValue<int>(); } catch { }
                        }
                    }
                    catch { }

                    // 解析 completion_tokens_details
                    try
                    {
                        var completionDetailsNode = usageNode["completion_tokens_details"];
                        if (completionDetailsNode != null)
                        {
                            this.usage.completion_tokens_details = new CompletionTokensDetails();
                            try { this.usage.completion_tokens_details.reasoning_tokens = completionDetailsNode["reasoning_tokens"]?.GetValue<int>(); } catch { }
                            try { this.usage.completion_tokens_details.audio_tokens = completionDetailsNode["audio_tokens"]?.GetValue<int>(); } catch { }
                            try { this.usage.completion_tokens_details.accepted_prediction_tokens = completionDetailsNode["accepted_prediction_tokens"]?.GetValue<int>(); } catch { }
                            try { this.usage.completion_tokens_details.rejected_prediction_tokens = completionDetailsNode["rejected_prediction_tokens"]?.GetValue<int>(); } catch { }
                        }
                    }
                    catch { }
                }
            }
            catch { }
        }
    }

    /// <summary>
    /// 表示响应中的一个补全选择。
    /// Represents a completion choice in the response.
    /// </summary>
    public class Choice
    {
        public Choice() { }

        /// <summary>
        /// 此选择在选择列表中的索引。
        /// The index of this choice in the list of choices.
        /// </summary>
        public int? index { get; set; } = 0;

        /// <summary>
        /// 此选择中由模型生成的消息。
        /// The message generated by the model for this choice.
        /// </summary>
        public ResponseMessage? message { get; set; }

        /// <summary>
        /// 输出令牌的对数概率信息。
        /// Log probability information for the output tokens.
        /// </summary>
        public object? logprobs { get; set; }

        /// <summary>
        /// 模型停止生成令牌的原因（例如 "stop" 或 "length"）。
        /// The reason the model stopped generating tokens (e.g., "stop" or "length").
        /// </summary>
        public string? finish_reason { get; set; }
    }

    /// <summary>
    /// 表示由模型生成的消息。
    /// Represents a message generated by the model.
    /// </summary>
    public class ResponseMessage
    {
        public ResponseMessage() { }

        /// <summary>
        /// 消息作者的角色，通常是 "assistant"。
        /// The role of the message's author, typically "assistant".
        /// </summary>
        public string? role { get; set; } = "assistant";

        /// <summary>
        /// 消息的文本内容。
        /// The text content of the message.
        /// </summary>
        public string? content { get; set; }

        /// <summary>
        /// 如果模型拒绝回答，此字段可能包含拒绝信息。
        /// If the model refused to answer, this field might contain refusal information.
        /// </summary>
        public string? refusal { get; set; }

        /// <summary>
        /// 与消息内容相关的注释列表。
        /// A list of annotations related to the message content.
        /// </summary>
        public List<object>? annotations { get; set; }
    }

    /// <summary>
    /// 表示请求的 token 使用情况。
    /// Represents the token usage for the request.
    /// </summary>
    public class Usage
    {
        public Usage() { }

        /// <summary>
        /// 提示（输入）中的 token 数量。
        /// The number of tokens in the prompt (input).
        /// </summary>
        public int? prompt_tokens { get; set; }

        /// <summary>
        /// 生成的补全（输出）中的 token 数量。
        /// The number of tokens in the generated completion (output).
        /// </summary>
        public int? completion_tokens { get; set; }

        /// <summary>
        /// 请求中使用的总 token 数量（prompt_tokens + completion_tokens）。
        /// The total number of tokens used in the request (prompt_tokens + completion_tokens).
        /// </summary>
        public int? total_tokens { get; set; }

        /// <summary>
        /// 提示 token 使用情况的详细分类。
        /// A detailed breakdown of prompt token usage.
        /// </summary>
        public PromptTokensDetails? prompt_tokens_details { get; set; }

        /// <summary>
        /// 补全 token 使用情况的详细分类。
        /// A detailed breakdown of completion token usage.
        /// </summary>
        public CompletionTokensDetails? completion_tokens_details { get; set; }
    }

    /// <summary>
    /// 提示 token 的详细信息。
    /// Details for prompt tokens.
    /// </summary>
    public class PromptTokensDetails
    {
        public PromptTokensDetails() { }

        /// <summary>
        /// 从缓存中检索的 token 数量。
        /// The number of tokens that were retrieved from a cache.
        /// </summary>
        public int? cached_tokens { get; set; }

        /// <summary>
        /// 与音频输入相对应的 token 数量。
        /// The number of tokens corresponding to audio input.
        /// </summary>
        public int? audio_tokens { get; set; }
    }

    /// <summary>
    /// 补全 token 的详细信息。
    /// Details for completion tokens.
    /// </summary>
    public class CompletionTokensDetails
    {
        public CompletionTokensDetails() { }

        /// <summary>
        /// 用于模型内部推理过程的 token 数量。
        /// The number of tokens used for the model's internal reasoning process.
        /// </summary>
        public int? reasoning_tokens { get; set; }

        /// <summary>
        /// 与生成的音频输出相对应的 token 数量。
        /// The number of tokens corresponding to generated audio output.
        /// </summary>
        public int? audio_tokens { get; set; }

        /// <summary>
        /// 来自已接受的推测性预测的 token 数量。
        /// The number of tokens from accepted speculative predictions.
        /// </summary>
        public int? accepted_prediction_tokens { get; set; }

        /// <summary>
        /// 来自被拒绝的推测性预测的 token 数量。
        /// The number of tokens from rejected speculative predictions.
        /// </summary>
        public int? rejected_prediction_tokens { get; set; }
    }
}
